import { HttpException, Injectable } from '@nestjs/common';
import { CreateMercadoproductDto } from 'src/dto/create-mercadoproduct.dto';
import { UpdateMercadoproductDto } from 'src/dto/update-mercadoproduct.dto';
import { Mercadoproduct } from 'src/entity/mercadoproduct.entity';
import { QueryMercadoproductDto } from 'src/dto/query-mercadoproduct.dto';
import { parseQueryParams } from 'src/common/utils';
import * as ExcelJS from 'exceljs';

import * as path from 'path';
import axios from 'axios';
import * as dayjs from 'dayjs';
import { Mercadosku } from 'src/entity/mercadosku.entity';

@Injectable()
export class MercadoproductService {
  create(createMercadoproductDto: CreateMercadoproductDto) {
    return Mercadoproduct.save({
      ...createMercadoproductDto,
    });
  }

  async findAll(pageNum: number, pageSize: number) {
    const [list, count] = await Mercadoproduct.findAndCount({
      skip: (pageNum - 1) * pageSize,
      take: pageSize,
    });

    return { list, count };
  }

  async likeQuery(likes: string) {
    try {
      let qeryBuilder = Mercadoproduct.createQueryBuilder('mercadoproduct');
      qeryBuilder
        .where('mercadoproduct.name like :likes', { likes: `%${likes}%` })
        .orWhere('mercadoproduct.number like :likes', { likes: `%${likes}%` })
        .orWhere('mercadoproduct.mercadoNumber like :likes', {
          likes: `%${likes}%`,
        });

      let [list, count] = await qeryBuilder.getManyAndCount();

      return { list, count };
    } catch (error) {
      throw new HttpException(error, 500);
    }
  }

  async query(query: QueryMercadoproductDto) {
    let qeryBuilder = Mercadoproduct.createQueryBuilder('mercadoproduct');

    let { queryClone, pageNum, pageSize } = parseQueryParams(query, [
      //  'categoryId',
    ]);

    qeryBuilder.where(queryClone);

    qeryBuilder.leftJoinAndSelect('mercadoproduct.mercadoskus', 'mercadoskus');

    qeryBuilder.leftJoinAndSelect('mercadoproduct.boxs', 'boxs');
    qeryBuilder.leftJoinAndSelect('mercadoskus.boxs', 'mercadoskuBoxs'); // 关联 mercadoskus 的 boxs

    qeryBuilder.skip((pageNum - 1) * pageSize);
    qeryBuilder.take(pageSize);
    qeryBuilder.orderBy('mercadoproduct.createTime', 'DESC');

    let [list, count] = await qeryBuilder.getManyAndCount();

    let calcList = [];

    for await (let item of list) {
      let obj = { ...item, totalBoxNum: 0, totalStockNum: 0, skuList: [] };

      obj.skuList = obj.mercadoskus.map((sku) => {
        let boxNumber = sku.boxs.reduce((pre, cur) => {
          if (cur.status == 1) {
            return pre + 1;
          } else {
            return pre;
          }
        }, 0);

        let stock = sku.boxs.reduce((pre, cur) => {
          if (cur.status == 1) {
            return pre + cur.boxNumber;
          } else {
            return pre;
          }
        }, 0);

        return {
          ...sku,
          boxNumber,
          stock,
        };
      });

      obj.totalBoxNum = obj.boxs.reduce((pre, cur) => {
        if (cur.status == 1) {
          return pre + 1;
        } else {
          return pre;
        }
      }, 0);

      obj.totalStockNum = obj.boxs.reduce((pre, cur) => {
        if (cur.status == 1) {
          return pre + cur.boxNumber;
        } else {
          return pre;
        }
      }, 0);

      calcList.push(obj);
    }

    return { list: calcList, count };
  }

  findOne(id: number) {
    return Mercadoproduct.findOneBy({ id });
  }

  update(id: number, updateMercadoproductDto: UpdateMercadoproductDto) {
    return Mercadoproduct.update(id, { ...updateMercadoproductDto });
  }

  remove(id: number) {
    return Mercadoproduct.update(id, { deleteTime: new Date() });
  }

  async excelExport(id: number) {
    let mercadoproduct = await Mercadoproduct.findOneBy({ id });

    let queryRunner = Mercadosku.createQueryBuilder('mercadosku');

    queryRunner.leftJoinAndSelect('mercadosku.boxs', 'boxs');

    queryRunner.where('mercadosku.mercadoproductId = :mercadoproductId', {
      mercadoproductId: id,
    });

    let skus = await queryRunner.getMany();

    const workbook = new ExcelJS.Workbook();
    const worksheet = workbook.addWorksheet('Sheet 1');

    // 设置表头
    worksheet.columns = [
      { header: '商品名称', key: 'productName', width: 20 },
      { header: 'SKU名称', key: 'name', width: 20 },
      { header: 'SKU图片', key: 'image', width: 20 },
      { header: '箱数', key: 'boxNumber', width: 20 },
      { header: '库存数', key: 'stock', width: 20 },
    ];

    skus.forEach((item: any, index: number) => {
      let tableRow = {
        productName: mercadoproduct.name,
        name: item.name,
        boxNumber: item.boxs.reduce((pre, cur) => {
          if (cur.status == 1) {
            return pre + 1;
          } else {
            return pre;
          }
        }, 0),
        stock: item.boxs.reduce((pre, cur) => {
          if (cur.status == 1) {
            return pre + cur.boxNumber;
          } else {
            return pre;
          }
        }, 0),
      };

      worksheet.addRow(tableRow);

      let imageId = workbook.addImage({
        filename: item.image.replace(`${process.env.BASE_REQUEST_URL}/`, 'public/'),
        extension: 'png',
      });

      worksheet.addImage(imageId, {
        tl: { col: 2, row: index + 1 }, // 图片起始位置，第 4 列（从 0 开始计数），当前行
        ext: { width: 30, height: 30 }, // 图片尺寸
      });
    });

    let fileName =
      dayjs().format('YYYYMMDD') +
      mercadoproduct.number +
      '-' +
      mercadoproduct.name +
      '商品库存';
    // 定义保存路径
    const filePath = path.join(__dirname, '../../public', fileName + '.xlsx');

    try {
      // 写入文件
      await workbook.xlsx.writeFile(filePath);
      return `${process.env.BASE_REQUEST_URL}/${fileName}.xlsx`;
    } catch (error) {
      console.error('保存 Excel 文件时出错:', error);
      throw error;
    }
  }
}
